package remote;

import com.alibaba.fastjson.JSONObject;
import org.jsoup.Connection;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import orm.dto.ServiceTrainDTO;
import utils.MyDateUtils;
import utils.StationUtil;

import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author yuyufeng
 * @date 2018/1/18
 */
@Service
public class Train12306Remote {
    private final Logger LOG = LoggerFactory.getLogger(this.getClass());

    public List<ServiceTrainDTO> searchTrainList(String begin, String end, String trainDate) throws Exception {
        List<ServiceTrainDTO> list;
        Map<String, String> cookies = getCookieMap(begin, end, trainDate);
        String cookieHeader = "";
        for (String cookie : cookies.keySet()) {
            cookieHeader = cookieHeader + cookie + "=" + cookies.get(cookie) + ";";
        }
        LOG.info("Cookie:" + cookieHeader);
        String beginCode = null;
        String endCode = null;
        try {
            beginCode = StationUtil.getStationByStationName(begin).getStationCode();
            endCode = StationUtil.getStationByStationName(end).getStationCode();
        } catch (Exception e) {
            LOG.error(e.getMessage());
        }
        Map<String, String> headers = new HashMap<String, String>(20);
        String host = "https://kyfw.12306.cn";
//        String path = "/otn/leftTicket/queryZ?leftTicketDTO.train_date="+trainDate+"&leftTicketDTO.from_station=SHH&leftTicketDTO.to_station=HZH&purpose_codes=ADULT";
        String path = "/otn/leftTicket/queryZ?leftTicketDTO.train_date=" + trainDate + "&leftTicketDTO.from_station=" + beginCode + "&leftTicketDTO.to_station=" + endCode + "&purpose_codes=ADULT";
        headers = new HashMap<>();
        headers.put("Accept", "*/*");
        headers.put("Accept-Encoding", "gzip, deflate, br");
        headers.put("Accept-Language", "zh-CN,zh;q=0.9");
        headers.put("Cache-Control", "no-cache");
        headers.put("Connection", "keep-alive");
        headers.put("Host", "kyfw.12306.cn");
        headers.put("If-Modified-Since", "0");
        headers.put("X-Requested-With", "XMLHttpRequest");
        headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36");
        headers.put("Referer", "https://kyfw.12306.cn/otn/leftTicket/init");
        headers.put("Cookie", cookieHeader + "RAIL_EXPIRATION=1516267056210; RAIL_DEVICEID=fj5ZdCpMH5HoTrckAdFRErbRpYTg49D9vBa3dNHV_HE5Ts97VaMBGDq0gWGX7wPOWRSvdz2FYcgqoUOPZNPP2h9WoLu4ctlp2ShbGsW4ct8tCXSiJ3CdRHnJrwZV66FzzlRSaA-UhMvka5Wf0_LSSSx_Tp-MJ6YY; _jc_save_toDate=" + MyDateUtils.getTodayString() + "; _jc_save_wfdc_flag=dc; acw_tc=AQAAAHT6iWilrQwASy/ieu2uTh/aGtsd; _jc_save_fromStation=%u4E0A%u6D77%2CSHH; _jc_save_toStation=%u676D%u5DDE%2CHZH; _jc_save_fromDate=" + trainDate);
        LOG.info("开始抓取：" + host + path);
        Connection conn = Jsoup.connect(host + path)
                .followRedirects(true)
                .method(Connection.Method.GET)
                .timeout(5000)
                .ignoreContentType(true)
                .headers(headers);

        Connection.Response response = conn.execute();
        Document doc = response.parse();
        String textResult = doc.body().text();
//        LOG.info(textResult);
        JSONObject jsonObject = null;
        try {
            jsonObject = JSONObject.parseObject(textResult);
        } catch (Exception e) {
            LOG.error(begin + end + trainDate + " 车次获取失败" + e.getMessage() + "返回报文："+ textResult);
            throw new Exception("网络可能存在问题，请您重试一下");
        }

        JSONObject jsonData = jsonObject.getJSONObject("data");
        String flag = jsonData.getString("flag");
        String map = jsonData.getString("map");
        String result = jsonData.getString("result");
        if ("1".equals(flag)) {
            list = new ArrayList<>(100);
        } else {
            LOG.info(begin + end + trainDate + " 车次获取失败");
            throw new Exception("获取失败");
        }
//        System.out.println(flag);
//        System.out.println(map);
//        System.out.println(result);

        result = result.replaceAll("\\[", "");
        result = result.replaceAll("\\]", "");
        LOG.info("====开始显示车次列表====");
        String[] trainContents = result.split(",");
        for (int i = 0; i < trainContents.length; i++) {
            String trainContent = trainContents[i];
            trainContent = trainContent.replaceAll("\"", "");
            String[] trainParams = trainContent.split("\\|");

            //如果不是车次信息，去掉
            if (trainParams.length < 30) {
                continue;
            }
            ServiceTrainDTO trainDTO = new ServiceTrainDTO();
//            trainDTO.key = trainParams[0];
//            trainDTO.operate = trainParams[1];
//            trainDTO.id = trainParams[2];
            trainDTO.trainNo = trainParams[3];
            trainDTO.startStation = trainParams[4];
            trainDTO.lastStation = trainParams[5];
            trainDTO.beginStation = trainParams[6];
            trainDTO.endStation = trainParams[7];
            trainDTO.beginTime = trainParams[8];      //发车时间
            trainDTO.endTime = trainParams[9];    //到达时间
            trainDTO.overTime = trainParams[10];    //历经时间
//            trainDTO.p5 = trainParams[11];
//            trainDTO.key2 = trainParams[12];
//            trainDTO.date = trainParams[13];        //出发日期
//            trainDTO.p6 = trainParams[14];
//            trainDTO.p7 = trainParams[15];
//            trainDTO.p8 = trainParams[16];
//            trainDTO.p9 = trainParams[17];
            trainDTO.seatBD = trainParams[32];          //商务
            trainDTO.seat1 = trainParams[31];         //一等座
            trainDTO.seat2 = trainParams[30];        //二等座
            trainDTO.bedSoftHigh = trainParams[21];     //高级软卧
            trainDTO.bedSoft = trainParams[23];     //软卧
            trainDTO.bedMove = trainParams[33];     //动卧
            trainDTO.bedHard = trainParams[28];     //硬卧
            trainDTO.seatSoft = trainParams[24];
            trainDTO.seatHard = trainParams[29];    //
            trainDTO.seatNo = trainParams[26];
            trainDTO.seatOther = trainParams[27];


            trainDTO.startStation = StationUtil.getStationByStationCode(trainDTO.startStation) == null ? trainDTO.startStation : StationUtil.getStationByStationCode(trainDTO.startStation).getStationName();
            trainDTO.lastStation = StationUtil.getStationByStationCode(trainDTO.lastStation) == null ? trainDTO.lastStation : StationUtil.getStationByStationCode(trainDTO.lastStation).getStationName();
            trainDTO.beginStation = StationUtil.getStationByStationCode(trainDTO.beginStation) == null ? trainDTO.beginStation : StationUtil.getStationByStationCode(trainDTO.beginStation).getStationName();
            trainDTO.endStation = StationUtil.getStationByStationCode(trainDTO.endStation) == null ? trainDTO.endStation : StationUtil.getStationByStationCode(trainDTO.endStation).getStationName();

            String overTimeTemp = trainDTO.overTime;
            trainDTO.overTime = overTimeTemp.split(":")[0] + "小时" + overTimeTemp.split(":")[1] + "分";


            list.add(trainDTO);
        }
        LOG.info(begin + end + trainDate + "查询到车次：" + list.size());
        return list;
    }

    private Map<String, String> getCookieMap(String begin, String end, String trainDate) throws IOException, Exception {
        String beginCode = null;
        String endCode = null;
        try {
            beginCode = StationUtil.getStationByStationName(begin).getStationCode();
            endCode = StationUtil.getStationByStationName(end).getStationCode();
        } catch (Exception e) {
            LOG.error(e.getMessage());
        }

        if (StringUtils.isEmpty(beginCode) || StringUtils.isEmpty(endCode)) {
            throw new Exception("找不到城市CODE");
        }

        Map<String, String> headers = new HashMap<>(20);
        headers.put("Accept", "*/*");
        headers.put("Accept-Encoding", "gzip, deflate, br");
        headers.put("Accept-Language", "zh-CN,zh;q=0.9");
        headers.put("Cache-Control", "no-cache");
        headers.put("Connection", "keep-alive");
        headers.put("Host", "kyfw.12306.cn");
        headers.put("If-Modified-Since", "0");
        headers.put("X-Requested-With", "XMLHttpRequest");
        headers.put("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36");
        headers.put("Referer", "https://kyfw.12306.cn/otn/index/init");
        headers.put("Origin", "https://kyfw.12306.cn");

        Map<String, String> datas = new HashMap<String, String>(10);
        datas.put("leftTicketDTO.from_station_name", begin);
        datas.put("leftTicketDTO.to_station_name", end);
        datas.put("leftTicketDTO.from_station", beginCode);
        datas.put("leftTicketDTO.to_station", endCode);
        datas.put("leftTicketDTO.train_date", trainDate);
        datas.put("leftTicketDTO.back_train_date", trainDate);
        datas.put("flag", "dc");
        datas.put("purpose_code", "ADULT");
        datas.put("pre_step_flag", "index");


        String host = "https://kyfw.12306.cn";
        String path = "/otn/leftTicket/init";

        LOG.info("开始抓取Cookie:" + host + path);
        Connection conn = Jsoup.connect(host + path)
                .followRedirects(false)
                .method(Connection.Method.POST)
                .ignoreContentType(true)
                .data(datas)
                .headers(headers);

        Connection.Response response = conn.execute();

        return response.cookies();
    }

    public static void main(String[] args) throws Exception {
        Train12306Remote train12306Remote = new Train12306Remote();
        List<ServiceTrainDTO> list = train12306Remote.searchTrainList("杭州", "贵阳", "2018-02-14");
        for (ServiceTrainDTO serviceTrainDTO : list) {
            System.out.println(serviceTrainDTO);
        }
    }
}
